package cc.vv.baselibrary.util.voice;

import android.content.Context;
import android.media.MediaRecorder;
import android.os.SystemClock;
import android.support.annotation.NonNull;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

import cc.vv.baselibrary.util.LKLogUtil;


/**
 * 语音录制操作
 * Created by nanPengFei on 2016/10/28 17:43.
 */
public class IMVoiceRecord {
    MediaRecorder mRecorder;
    /**
     * 格式
     */
    private final String EXTENSION = "amr";
    /**
     * 是否正在录音
     */
    private boolean mIsRecording = false;
    /**
     * 开始时间
     */
    private long mStartTime;
    /**
     * 语音文件路径
     */
    private String mVoiceFilePath = null;
    /**
     * 语音文件名称
     */
    private String mVoiceFileName = null;
    /**
     * 语音文件
     */
    private File mVoiceFile;
    /**
     * 录音状态监听
     */
    private RecorderInter mRecorderInter;
    private WeakReference<Context> mContext;

    /**
     * 构造初始化
     *
     * @param context
     * @param inter
     */
    public IMVoiceRecord(@NonNull Context context, @NonNull RecorderInter inter) {
        mContext = new WeakReference<>(context);
        this.mRecorderInter = inter;
    }

    /**
     * 开始录制
     */
    public String start() {
        String filePath = null;
        mVoiceFile = null;
        try {
            if (mRecorder != null) {
                mRecorder.release();
                mRecorder = null;
            }
            mRecorder = new MediaRecorder();
            /*设置麦克风*/
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            /* ②设置音频文件的编码：AAC/AMR_NB/AMR_MB/Default 声音的（波形）的采样 */
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
            /*
			 * ②设置输出文件的格式：THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
			 * ，H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
			 */
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mRecorder.setAudioChannels(1);
            mRecorder.setAudioSamplingRate(8000);
            mRecorder.setAudioEncodingBitRate(64);
            mVoiceFileName = getFileName();
            mVoiceFile = createFile();
            mVoiceFilePath = mVoiceFile.getAbsolutePath();
            mRecorder.setOutputFile(mVoiceFilePath);
            mRecorder.prepare();
            mIsRecording = true;
            mRecorder.start();
            mStartTime = new Date().getTime();
            new Thread(new Runnable() {//通知当前总秒数
                @Override
                public void run() {
                    int duration = 0;
                    while (mIsRecording) {
                        SystemClock.sleep(1000);
                        duration = duration + 1;
                        mRecorderInter.duration(duration);
                    }
                }
            }).start();
            new Thread(new Runnable() {//通知振幅
                @Override
                public void run() {
                    try {
                        while (mIsRecording) {
                            if(null!=mRecorder && null!=mRecorderInter){
                                int maxAmplitude = mRecorder.getMaxAmplitude();
                                LKLogUtil.e("MaxAmplitude:"+maxAmplitude);
                                mRecorderInter.amplitude(maxAmplitude * 13 / 0x7FFF);
                                SystemClock.sleep(100);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        LKLogUtil.e(e.toString(),e);
                    }
                }
            }).start();
            filePath = mVoiceFile == null ? null : mVoiceFile.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
            mRecorderInter.noPermission();//通知没有权限并关闭弹窗
            stopAndDelete();
        }
        return filePath;
    }


    /**
     * 停止录音并删除记录
     */
    public void stopAndDelete() {
        if (mRecorder != null) {
            try {
                mRecorder.stop();
                mRecorder.release();
                mRecorder = null;
                deleteFile(mVoiceFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
            mIsRecording = false;
        }
    }

    /**
     * 删除语音文件
     *
     * @param voiceFile
     */
    public void deleteFile(File voiceFile) {
        if (voiceFile != null && voiceFile.exists() && !voiceFile.isDirectory()) {
            voiceFile.delete();
        }
    }


    /**
     * 停止录音
     *
     * @return
     */
    public void stop() {
        try {
            if (mRecorder != null) {
                mIsRecording = false;
                mRecorder.stop();
                mRecorder.release();
                mRecorder = null;
                if (mVoiceFile == null || !mVoiceFile.exists() || !mVoiceFile.isFile()) {
                    mRecorderInter.fail();
                    return;
                }
                if (mVoiceFile != null && mVoiceFile.length() == 0) {
                    mVoiceFile.delete();
                    mRecorderInter.fail();
                    return;
                }
                int seconds = (int) (new Date().getTime() - mStartTime) / 1000;
                mRecorderInter.stop(seconds, mVoiceFilePath, mVoiceFileName, mVoiceFile);
            } else {
                mRecorderInter.fail();
            }
        } catch (Exception e) {
            e.printStackTrace();
            mRecorderInter.noPermission();
            mRecorderInter.fail();
        }

    }


    /**
     * 判断是否正在录音
     *
     * @return
     */
    public boolean isRecording() {
        return mIsRecording;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if (mRecorder != null) {
            mRecorder.release();
        }
    }

    /**
     * 获取文件名称
     *
     * @return
     */
    private String getFileName() {
        return String.format(Locale.CHINESE, "%s.%s", UUID.randomUUID().toString(), EXTENSION);
    }

    /**
     * 创建语音文件
     *
     * @return
     */
    private File createFile() {
        File logFileDir = mContext.get().getExternalFilesDir("voice");
        return new File(logFileDir, mVoiceFileName);
    }

    /**
     * 录音回调
     */
    public interface RecorderInter {
        /**
         * 无权限
         */
        void noPermission();

        /**
         * 振幅
         *
         * @param amplitude
         */
        void amplitude(int amplitude);

        /**
         * 语音长度
         *
         * @param duration
         */
        void duration(int duration);

        /**
         * 停止录音
         *
         * @param duration
         * @param path
         * @param name
         * @param file
         */
        void stop(int duration, String path, String name, File file);

        /**
         * 失败
         */
        void fail();
    }

}
